Terraform Stacksの構成要素を図解してみる

Terraform Stacksの構成要素を図解してみる

Clock Icon2024.10.23

HashiConf 2024でTerraform Stacksがパブリックベータになりました。

https://www.hashicorp.com/blog/terraform-packer-nomad-and-waypoint-updates-help-scale-ilm-at-hashiconf-2024

Terraform Stacksによって新しい構成要素がいくつか追加されたので、できるだけ図を使って説明していきます。

Terraform Stacksとは

Stacks are a powerful configuration layer in HCP Terraform that simplifies managing your infrastructure modules and then repeating that infrastructure.
スタックは、インフラストラクチャ モジュールの管理とそのインフラストラクチャの繰り返しを簡素化する、HCP Terraform の強力な構成レイヤーです。

Stacks Overview | Terraform | HashiCorp Developerから引用

ざっくり説明すると、複数Workspaceが必要な構成を、簡単に作れる機能です。

例えば以下のケースでは、複数のWorkspaceを必要とします。

  • 本番、ステージング、開発等 同一構成の複数環境を構築する
  • 複数リージョンに同一構成の環境を構築する
    • Multiple Provider Configurations不使用、Statefileを分割
  • Kubernetesワークロードを構築する
    • CRDを登録して、カスタムリソースを作成する等

個別にWorkspaceを作る場合、それぞれVCSやトリガーの設定等を行う必要があります。

Terraform Stacksを使って構成することで、この手間を削減できます。

本番・ステージング・開発の3環境を作る場合、WorkspaceとStacks構成のイメージは以下です。

Workspace

Stacks

StacksはProject配下に作成します。Deploymentsという単位で、State管理・Terraform実行されます。

Workspaceのように、HCP Terraform上のVariablesはありません。環境毎に異なる値は、コード上で指定する形になります。

Untitled(4)

注意点

現時点では、HCP Terraformで利用可能です。一部の機能はコミュニティ版にも組み込まれる予定とのことです。

現時点では、500 Resouceまでの制限があるため、合わせてご注意ください。(有償プランを契約している場合も同様です)

While our public beta is limited to HCP Terraform plans based on resources under management (RUM), certain Stacks functionality will be incorporated in upcoming releases of the community edition of Terraform.

https://www.hashicorp.com/blog/terraform-stacks-explained

Terraform Stacksの構成要素

https://developer.hashicorp.com/terraform/tutorials/cloud/stacks-deploy

Terraform Stacksの構成要素は以下の4つです。

  • Components
  • Deployments
  • Orchestration rules
  • Deferred changes

Stacksを利用するには、ComponentsとDeploymentsは必須です。

Orchestration rulesとDeferred changesは設定しなくても、Terraform Stacksを利用することは可能です。

API Gateway + Lambda + S3の構成をPROD・STG・DEVの3環境作成を例に、Terraform Stacksを説明します。

archi

Components

スタックに含めるリソースを定義します。

components

tfstack.hclという拡張子でファイルを作成し、componentブロックを定義します。

componentブロックでは、モジュールやプロバイダーを指定します。(以下、s3用のComponentsです)

components.tfstack.hcl
component "s3" {
  for_each = var.regions

  source = "./s3"

  inputs = {
    region = each.value
  }

  providers = {
    aws    = provider.aws.configurations[each.value]
    random = provider.random.this
  }
}

注意点として、モジュールは現時点(2024/10時点)では、プライベートレジストリからのモジュールはサポートしていません。(パブリックレジストリはサポートしている)

ちなみに、providerもファイル拡張子tfstack.hclで定義します。

providers.tfstack.hcl
required_providers {
  aws = {
    source  = "hashicorp/aws"
    version = "~> 5.7.0"
  }
}
provider "aws" "configurations" {
  for_each = var.regions

  config {
    region = each.value

    assume_role_with_web_identity {
      role_arn           = var.role_arn
      web_identity_token = var.identity_token
    }
  }
}

https://developer.hashicorp.com/terraform/language/stacks/reference/tfstack

Deployments

デプロイする場所を定義します。(AWSなら、AWSアカウント・リージョン等)

deployments

tfdeploy.hclという拡張子でファイルを作成し、deploymentブロックを定義します。

Terraform実行用のIAMロールや対象リージョンを指定します。

PROD・STG・DEVの3環境を用意するため、それぞれdeploymentブロックを定義しています。

identity_token "aws" {
  audience = ["aws.workload.identity"]
}

deployment "prod" {
  inputs = {
    regions        = ["us-east-1"]
    role_arn       = "<PRDアカウント IAM Role ARN>"
    identity_token = identity_token.aws.jwt
  }
}

deployment "stg" {
  inputs = {
    regions     = ["us-east-1"]
    role_arn       = "<STGアカウント IAM Role ARN>"
    identity_token = identity_token.aws.jwt
  }
}

deployment "dev" {
  inputs = {
    regions        = ["us-east-1"]
    role_arn       = "<DEVアカウント IAM Role ARN>"
    identity_token = identity_token.aws.jwt
  }
}

identity_tokenブロックは、jwtトークンを生成します。

provider定義で以下のようにjwtトークンとIAMロールを受け取っています。

providers.tfstack.hcl
# 省略
provider "aws" "configurations" {
  for_each = var.regions

  config {
    region = each.value

    assume_role_with_web_identity {
      role_arn           = var.role_arn
      web_identity_token = var.identity_token
    }
  }
}

https://developer.hashicorp.com/terraform/language/stacks/reference/tfdeploy

Orchestration rules

Deploymentsの管理に使用できるルールを定義できます。

現時点では、2つのルールがサポートされており、チェックに合格時に以下の動作が行われます。

  • auto_approve: 自動承認(承認時にterraform apply相当が行われる)
  • replan: Planを再実行

以下のルールは、Planの内容に削除が含まれていなければ、自動的にPlanを承認します。

orchestrate "auto_approve" “safe_plans” {
  check {
    #check that there are no resources being removed
    condition = context.plan.changes.remove == 0
    reason = "Plan has ${context,plan.changes. remove} resources to be removed."
  }
}

https://developer.hashicorp.com/terraform/language/stacks/reference/tfdeploy#orchestrate-block-configuration

Deferred changes

Componentsの依存関係を管理する機能です。

例えば、カスタムリソースを使うKubernetesワークロードを管理するケースを考えます。

CRDが存在しない状態でカスタムリソースを作成することはできないので、これは一つの手順で行うことができません。

そのため、CRDを登録が終わった後にカスタムリソース作成をする必要があります。

以下で、component.clustercomponent.kubeを依存関係を指定できます。

component "cluster" {
  source = "./cluster"

  providers = {
    aws = provider.aws.main
    random = provider.random.main
  }

  inputs = {
    cluster_name    = var.cluster_name
    kubernetes_version = var.kubernetes_version
    region = var.region
  }
}

component "kube" {
  source = "./kube"

  providers = {
    kubernetes = provider.kubernetes.main
  }
}
providers.tfstack.hcl
provider "kubernetes" "main" {
  config {
    host                = component.cluster.cluster_url
    cluster_ca_certificate = component.cluster.cluster_ca
    token               = component.cluster.cluster_token
  }
}

provider.kubernetes.maincomponent.clusterの出力値を指定しているため、依存関係を解釈して自動的にcomponent.kubeの実行を延期します。

https://developer.hashicorp.com/terraform/tutorials/cloud/stacks-eks-deferred

おわりに

Terraform Stacksの概要部分の説明でした。この後チュートリアルやってみたブログも公開する予定です。

https://developer.hashicorp.com/terraform/tutorials/cloud/stacks-deploy

実際の画面のイメージは以下のブログを参照いただくと良さそうです。

https://techblog.ap-com.co.jp/entry/2024/10/21/190000?utm_source=feed

以上、AWS事業本部の佐藤(@chari7311)でした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.